package org.tg.search.service.impl;


import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

import org.tg.client.activity.ActivityFeignClient;
import org.tg.client.product.ProductFeignClient;
import org.tg.common.auth.AuthContextHolder;
import org.tg.enums.SkuType;
import org.tg.model.activity.SeckillSku;
import org.tg.model.product.Category;
import org.tg.model.product.SkuInfo;
import org.tg.model.search.SkuEs;
import org.tg.search.repository.SkuRepository;
import org.tg.search.service.SkuService;
import org.tg.vo.search.SkuEsQueryVo;

import java.util.List;

/**
 * @Author Glow
 * @Date 2023-07-04 14:54:33
 * @Description
 * @Version 1.0
 */
@Slf4j
@Service
public class SkuServiceImpl implements SkuService {

    @Autowired
    private ProductFeignClient productFeignClient;
    @Autowired
    private ActivityFeignClient activityFeignClient;
    @Autowired
    private SkuRepository skuEsRepository;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public Page<SkuEs> search(Pageable pageable, SkuEsQueryVo skuEsQueryVo) {
       System.out.println(skuEsQueryVo.toString());
        skuEsQueryVo.setWareId(AuthContextHolder.getWareId());
        Page<SkuEs> page = null;
        if(StringUtils.isEmpty(skuEsQueryVo.getKeyword())) {
            page = skuEsRepository.findByCategoryIdAndWareId(skuEsQueryVo.getCategoryId(), skuEsQueryVo.getWareId(), pageable);
        } else {
            page = skuEsRepository.findByKeywordAndWareId(skuEsQueryVo.getKeyword(), skuEsQueryVo.getWareId(), pageable);
        }

        List<SkuEs>  skuEsList =  page.getContent();

        //如果es没有数据，则放入sku信息
        if(CollectionUtils.isEmpty(skuEsList)) {
            List<SkuInfo> list = productFeignClient.getSkuListByCategoryId(skuEsQueryVo.getCategoryId());
            for(int i = 0 ; i < list.size(); i++)
            {
                SkuEs skuEs = new SkuEs();
                skuEs.setId(list.get(i).getId());
                skuEs.setKeyword(list.get(i).getSkuName());
                skuEs.setSkuType(list.get(i).getSkuType());
                skuEs.setIsNewPerson(list.get(i).getIsNewPerson());
                skuEs.setCategoryId(list.get(i).getCategoryId());
                Category category = productFeignClient.getCategory(list.get(i).getCategoryId());
                skuEs.setCategoryName(category.getName());
                skuEs.setImgUrl(list.get(i).getImgUrl());
                skuEs.setTitle(list.get(i).getSkuName());
                skuEs.setPrice(list.get(i).getPrice().doubleValue());
                skuEs.setStock(list.get(i).getStock());
                skuEs.setPerLimit(list.get(i).getPerLimit());
                skuEs.setSale(list.get(i).getSale());
                skuEs.setWareId(list.get(i).getWareId());

                skuEsRepository.save(skuEs);

//                skuEs.setHotScore();
            }
            page = skuEsRepository.findByCategoryIdAndWareId(skuEsQueryVo.getCategoryId(), skuEsQueryVo.getWareId(), pageable);
            List<Long> skuIdList = skuEsList.stream().map(sku -> sku.getId()).collect(Collectors.toList());
            Map<Long, List<String>> skuIdToRuleListMap = activityFeignClient.findActivity(skuIdList);
            if(null != skuIdToRuleListMap) {
                skuEsList.forEach(skuEs -> {
                    skuEs.setRuleList(skuIdToRuleListMap.get(skuEs.getId()));
                });
            }
        }
        //获取sku对应的促销活动标签
        else{
            List<Long> skuIdList = skuEsList.stream().map(sku -> sku.getId()).collect(Collectors.toList());
            Map<Long, List<String>> skuIdToRuleListMap = activityFeignClient.findActivity(skuIdList);
            if(null != skuIdToRuleListMap) {
                skuEsList.forEach(skuEs -> {
                    skuEs.setRuleList(skuIdToRuleListMap.get(skuEs.getId()));
                });
            }
        }
        return page;
    }

    @Override
    public List<SkuEs> findHotSkuList() {
        Pageable pageable = PageRequest.of(0,10);
        Page<SkuEs> pageModel = skuEsRepository.findByOrderByHotScoreDesc(pageable);
        List<SkuEs> skuEsList = pageModel.getContent();
        System.out.println("List<SkuEs>:"+skuEsList);
        return skuEsList;
    }

    /**
     * 上架商品列表
     * @param skuId
     */
    @Override
    public void upperSku(Long skuId) {
        log.info("upperSku："+skuId);
        SkuEs skuEs = new SkuEs();

        //查询sku信息
        SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
        if(null == skuInfo) {
            return;
        }

        // 查询分类
        Category category = productFeignClient.getCategory(skuInfo.getCategoryId());
        if (category != null) {
            skuEs.setCategoryId(category.getId());
            skuEs.setCategoryName(category.getName());
        }
        skuEs.setId(skuInfo.getId());
        skuEs.setKeyword(skuInfo.getSkuName()+","+skuEs.getCategoryName());
        skuEs.setWareId(skuInfo.getWareId());
        skuEs.setIsNewPerson(skuInfo.getIsNewPerson());
        skuEs.setImgUrl(skuInfo.getImgUrl());
        skuEs.setTitle(skuInfo.getSkuName());
        if(skuInfo.getSkuType() == SkuType.COMMON.getCode()) {
            skuEs.setSkuType(0);
            skuEs.setPrice(skuInfo.getPrice().doubleValue());
            skuEs.setStock(skuInfo.getStock());
            skuEs.setSale(skuInfo.getSale());
            skuEs.setPerLimit(skuInfo.getPerLimit());
        } else {
            //已完善-秒杀商品
            skuEs.setSkuType(1);
         SeckillSku seckillSku = activityFeignClient.getSeckillSkuBySkuId(skuId.intValue());
            skuEs.setPrice(seckillSku.getSeckillPrice().doubleValue());
            skuEs.setStock(seckillSku.getSeckillStock());
            skuEs.setSale(seckillSku.getSeckillSale());
            skuEs.setPerLimit(seckillSku.getSeckillLimit());
        }
        //        因为ES版本过高，导致返回响应无法接受报错，数据是没问题的，加try-catch异常处理即可。
        try{
            SkuEs save = skuEsRepository.save(skuEs);
            log.info("upperSku："+ JSON.toJSONString(save));
        }catch (Exception exception){
            if(!((exception.getMessage()).contains("Created")||(exception.getMessage()).contains("HTTP/1.1 200 OK"))){
                throw exception;
            }
        }

    }

    /**
     * 下架商品列表
     * @param skuId
     */
    @Override
    public void lowerSku(Long skuId) {
//        因为ES版本过高，导致返回响应无法接受报错，数据是没问题的，加try-catch异常处理即可。
        System.out.println("删除前的skuId:"+skuId);
        try{
            this.skuEsRepository.deleteById(skuId);
        }catch (Exception e)
        {
            //ES 如果查找成功就是contain "true",更新成功就是updated
            if(!(
                    (e.getMessage()).contains("response=HTTP/1.1 200 OK") ||
                               (e.getMessage()).contains("deleted"))){
                log.info("错误信息为："+e.getMessage());
                throw e;
            }
        }

    }

    @Override
    public void incrHotScore(Long skuId) {
        String key = "hotScore";
        //redis保存数据，每次+1
        Double hotScore = redisTemplate.opsForZSet().incrementScore(key, "skuId:" + skuId, 1);
        //规则
        if (hotScore % 10 == 0) {
            //更新es
            Optional<SkuEs> optional = skuEsRepository.findById(skuId);
            SkuEs skuEs = optional.get();
            skuEs.setHotScore(Math.round(hotScore));
            skuEsRepository.save(skuEs);
        }
    }
}